﻿using System.Collections.Generic;
using System.IO;
using System.Text;

namespace SqlToCsharp
{
    class Generator
    {
        private static Encoding Encoding => Encoding.UTF8;

        /// <summary>
        /// generate C# classes and save them to files.
        /// </summary>
        public static void Save(string @namespace, IEnumerable<TableInfo> tables, string targetFolder)
        {
            foreach (var t in tables)
            {
                Save(@namespace, t, targetFolder);
            }
        }

        /// <summary>
        /// generate a C# class and save it to a file.
        /// </summary>
        public static void Save(string @namespace, TableInfo t, string targetFolder)
        {
            var targetFile = Path.Combine(targetFolder, t.Name + ".cs");

            var generated = Generate(@namespace, t);

            if (Directory.Exists(targetFolder))
                Directory.CreateDirectory(targetFolder);

            // skip if generated file is binary equal to exists.
            if (File.Exists(targetFile) && File.ReadAllText(targetFile, Encoding) == generated)
            {
                return;
            }

            File.WriteAllText(targetFile, generated, Encoding.UTF8);
        }

        /// <summary>
        /// generate a C# class from <see cref="TableInfo"/>
        /// </summary>
        public static string Generate(string @namespace, TableInfo t)
        {
            var builder = new StringBuilder();

            builder.Append($@"// Code generated by SqlToCsharp

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace {@namespace}
{{
    public partial class {t.Name}
    {{
");

            foreach (var c in t.Columns)
            {
                if(c.KeyColumnOrder is int order)
                {
                    builder.AppendLine("        [Key]");
                    builder.AppendLine($"        [Column(Order = {order})]");
                }
                foreach (var at in c.Attributes)
                {
                    builder.AppendLine($"        [{at}]");
                }
                builder.AppendLine($"        public {c.TypeName} {c.Name} {{ get; set; }}");
            }

            builder.Append(@"    }
}
");

            return builder.ToString();
        }
    }
}
